package com.jy.api.controller.clerk;

import com.jy.api.dao.*;
import com.jy.api.domain.*;
import com.jy.api.enums.DistributeType;
import com.jy.api.enums.StoreLevel;
import com.jy.api.payRes.CouponInstanceDto;
import com.jy.api.service.CouponService;
import com.jy.api.signUpReq.admin.DistributeCouponSignUpReq;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.Predicate;
import javax.validation.Valid;
import java.security.Principal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by lihu on 2017/11/17.
 */
@Slf4j
@RestController
@RequestMapping(value = "v1/clerk", produces = "application/json;charset=utf-8")
public class ClerkCouponController {

    @Autowired
    CouponService couponService;
    @Autowired
    private EmployeeDao employeeDao;
    @Autowired
    private CouponDao couponDao;
    @Autowired
    private CouponInstanceDao couponInstanceDao;
    @Autowired
    private StoreDao storeDao;
    @Autowired
    private MemberDao memberDao;



    /**
     * 优惠卷派发
     *
     * @param signUpReq
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "/distribute-coupon")
    public ResponseEntity distributeCoupon(@Valid @RequestBody DistributeCouponSignUpReq signUpReq,
                                           BindingResult bindingResult, Principal principal) {
        try {
            if (bindingResult.hasErrors()) {
                return new ResponseEntity(bindingResult.getFieldError().getDefaultMessage(), HttpStatus.BAD_REQUEST);
            }
            Store store = storeDao.findOne(signUpReq.getStoreId());
            if (store == null) {
                return new ResponseEntity("派发失败！店铺信息有误！！", HttpStatus.BAD_REQUEST);
            }

            if (store.getLevel() != StoreLevel.THREE) {
                return new ResponseEntity("当前店铺版本过低！请升级！", HttpStatus.BAD_REQUEST);
            }

            Employee employee = employeeDao.findByStoreIdAndUsernameAndEnabled(signUpReq.getStoreId(),
                    principal.getName(), true);
            if (employee == null) {
                return new ResponseEntity("派发失败！账号信息有误！", HttpStatus.BAD_REQUEST);
            }
            Coupon coupon = couponService.getFondId(signUpReq.getCouponId());
            if (coupon == null || !coupon.isEnabled()) {
                return new ResponseEntity("派发失败！优惠卷信息不存在！", HttpStatus.BAD_REQUEST);
            }

            if (signUpReq.getDistributeType() == DistributeType.SINGLE && signUpReq.getMemeberIds().size() == 0) {
                return new ResponseEntity("派发失败！未选择派发会员信息！", HttpStatus.BAD_REQUEST);
            }
            log.info("派发人{},派发优惠券{},派发数量{},收券人{}",employee.getName(),coupon,signUpReq.getQty(),signUpReq.getMemeberIds());
            couponService.distributeCoupon(signUpReq, coupon, employee.getUsername(), employee.getName());
            return new ResponseEntity(HttpStatus.OK);
        } catch (Exception ex) {
            log.error("getCouponInstance  is error==> signUpReq{}", signUpReq, ex);
            return new ResponseEntity("系统运行错误", HttpStatus.INTERNAL_SERVER_ERROR);
        }

    }

    /**
     * 获取优惠卷信息
     *
     * @param storeId
     * @param pageable
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "coupon")
    public ResponseEntity coupon(@RequestParam(value = "storeId") String storeId,@RequestParam("userName")String userName,
                                 @PageableDefault(value = 10, sort = {"addTime"},
                                         direction = Sort.Direction.DESC) Pageable pageable) {
        Employee employee = employeeDao.findByStoreIdAndUsernameAndEnabled(storeId,userName,true);
        if (employee.isSendCouponEnabled()){
            return new ResponseEntity(couponService.getCoupon(storeId, pageable), HttpStatus.OK);
        }else {
            return ResponseEntity.badRequest().body("暂无权限，请联系管理员！");
        }

    }

    /**
     * 单张优惠卷信息获取
     *
     * @param id
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/{id}/coupon")
    public ResponseEntity getCoupon(@PathVariable String id) {
        return new ResponseEntity(couponService.getFondId(id), HttpStatus.OK);
    }


    /**
     * 获取优惠卷信息
     *
     * @param storeId
     * @param pageable
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/coupon/list")
    public ResponseEntity couponList(@RequestParam(value = "storeId") String storeId, @PageableDefault(value = 10, sort = {"addTime"},
            direction = Sort.Direction.DESC) Pageable pageable) {
        return new ResponseEntity(couponService.getCouponAll(storeId, pageable), HttpStatus.OK);
    }


    /**
     * 优惠卷详情
     *
     * @param
     * @param
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/coupon/detail")
    public ResponseEntity couponDetail(@RequestParam("memberId") String memberId, @RequestParam("status") CouponInstanceStatus status,
                                       @RequestParam("couponId") String couponId, @PageableDefault(value = 10) Pageable pageable) {
        Coupon coupon = couponDao.findOne(couponId);
        if (coupon == null) {
            return new ResponseEntity("优惠券不存在，请刷新后重试", HttpStatus.BAD_REQUEST);
        }
        Specification<CouponInstance> spec = (root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtils.isNotBlank(memberId)){
                predicates.add(criteriaBuilder.equal(root.get("ownerId"),memberId));
            }
            if (!status.equals(CouponInstanceStatus.STOP)){
                predicates.add(criteriaBuilder.notEqual(root.get("stauts"),CouponInstanceStatus.STOP));
            }else {
                predicates.add(criteriaBuilder.equal(root.get("stauts"),status));
            }
            predicates.add(criteriaBuilder.equal(root.get("couponId"),couponId));
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        Page<CouponInstance> couponInstances =couponInstanceDao.findAll(spec, new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), new Sort(Sort.Direction.DESC, "ownerId","addTime")));
        List<CouponInstanceDto> couponInstanceDtos = new ArrayList<>();
        for (CouponInstance couponInstance : couponInstances) {
            if (!StringUtils.isBlank(couponInstance.getOwnerId())){
                Member member = memberDao.findOne(couponInstance.getOwnerId());
                CouponInstanceDto dto = new CouponInstanceDto();
                BeanUtils.copyProperties(couponInstance, dto);
                dto.setMemberName(member.getName());
                dto.setMobile(null== member.getMobile() ?  "":member.getMobile());
                couponInstanceDtos.add(dto);
            }
        }
        Map map = new HashMap();
        map.put("data", couponInstanceDtos);
        map.put("totalElements", couponInstances.getTotalElements());
        map.put("totalPages", couponInstances.getTotalPages());
        return new ResponseEntity(map, HttpStatus.OK);
    }

}
